<template>
    <div :class="exampleBlockClass" @mouseenter="hover = true" @mouseleave="hover = false">
        <div class="example">
            <slot />
        </div>
        <div class="source-code-container" :style="sourceCodeContainerStyle">
            <div v-if="$slots.description" ref="description" class="description">
                <slot name="description" />
            </div>
            <div ref="highlightRef" class="highlight">
                <slot name="highlight" />
            </div>
        </div>
        <div class="control-panel" @click="onClickControl">
            <transition name="arrow-slide">
                <i :class="controlIconClass"></i>
            </transition>
            <transition name="text-slide">
                <span v-show="hover" class="control-text">{{ controlText }}</span>
            </transition>
            <div class="control-button-wrap">
                <transition name="text-slide">
                    <span v-show="isExpanded" class="control-button copy-button" @click.stop="onCopy">
                        {{ copyText }}
                    </span>
                </transition>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import { useData } from 'vitepress';
import { ref, computed, SetupContext, Ref } from 'vue';
import { useCollapse } from './composition/use-collapse';
import { useCopy } from './composition/use-copy';

export default {
    name: 'FExample',
    props: {
        sourceCode: String
    },
    setup(props: any, setupContext: SetupContext) {
        const highlightRef = ref<HTMLElement>();
        const data = useData();
        const hover = ref(false);
        const locale = computed(() => {
            return (
                data.theme.value.demoblock?.[data.localePath.value] ?? {
                    'hide-text': '隐藏代码',
                    'show-text': '显示代码',
                    'copy-button-text': '复制代码片段',
                    'copy-success-text': '复制成功'
                }
            );
        });

        const { copyText, onCopy } = useCopy(props, setupContext, locale);
        const { controlText, isExpanded, onClickControl } = useCollapse(props, setupContext, locale);

        const exampleBlockClass = computed(() => ({
            'example-block': true,
            hover: hover.value
        }));

        const controlIconClass = computed(() => ({
            'control-icon': true,
            'icon-caret-down': !isExpanded.value,
            'icon-caret-up': isExpanded.value,
            hovering: hover.value
        }));

        const sourceCodeContainerStyle = computed(() => ({
            height: isExpanded.value ? 'auto' : '0'
        }));

        return {
            exampleBlockClass,
            controlIconClass,
            sourceCodeContainerStyle,
            hover,
            isExpanded,
            controlText,
            onClickControl,
            copyText,
            onCopy
        };
    }
};
</script>

<style scoped>
.example-block {
    margin: 10px 0;
    border: solid 1px var(--vp-c-divider-light);
    border-radius: 3px;
    transition: 0.2s;
}

.example-block.hover {
    /* box-shadow: 0 0 8px 0 rgba(232, 237, 250, 0.6), 0 2px 4px 0 rgba(232, 237, 250, 0.5); */
    box-shadow: var(--vp-shadow-2);
}

.example {
    box-sizing: border-box;
    padding: 24px;
    transition: 0.2s;
    overflow: auto;
}

.source-code-container {
    border-top: solid 1px var(--vp-c-divider-light);
    background-color: var(--code-bg-color);
    overflow: hidden;
    height: 0;
    transition: 0.2s;
}

.description {
    border: solid 1px var(--vp-c-divider-light);
    border-radius: 3px;
    padding: 20px;
    box-sizing: border-box;
    line-height: 26px;
    color: var(--vp-c-text-2);
    word-break: break-word;
    margin: 10px 10px 6px 10px;
    background-color: var(--code-bg-color);
}

.control-panel {
    border-top: solid 1px var(--vp-c-divider-light);
    height: 44px;
    box-sizing: border-box;
    background-color: var(--code-bg-color);
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
    text-align: center;
    margin-top: -1px;
    color: var(--vp-c-text-2);
    cursor: pointer;
    position: relative;
}

.control-panel .control-icon {
    display: inline-block;
    font-size: 16px;
    line-height: 44px;
    transition: 0.3s;
}
.control-panel .control-icon.hovering {
    transform: translateX(-40px);
}

.control-panel .control-text {
    position: absolute;
    transform: translateX(-30px);
    font-size: 14px;
    line-height: 44px;
    font-weight: 500;
    transition: 0.3s;
    display: inline-block;
}

.control-panel:hover {
    color: var(--c-brand);
    background-color: var(--vp-c-bg-soft);
}

.control-panel .text-slide-enter,
.control-panel .text-slide-leave-active {
    opacity: 0;
    transform: translateX(10px);
}

.control-panel .control-button {
    padding: 13px 0;
    color: var(--c-brand);
    font-size: 14px;
    font-weight: 500;
    margin: 0 10px;
}

.control-panel .control-button-wrap {
    line-height: 43px;
    position: absolute;
    top: 0;
    right: 0;
    padding-left: 5px;
    padding-right: 25px;
}
.highlight div[class*='language-'] {
    margin: 0 !important;
}

/* icon-caret */
.icon-caret-down {
    width: 16px;
    height: 100%;
    position: relative;
}

.icon-caret-down::before {
    content: '';
    width: 0;
    height: 0;
    border: 6px solid transparent;
    border-top: 7.5px solid;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -2.5px;
    margin-left: -6px;
}

.icon-caret-up {
    width: 16px;
    height: 100%;
    position: relative;
}

.icon-caret-up::before {
    content: '';
    width: 0;
    height: 0;
    border: 6px solid transparent;
    border-bottom: 7px solid;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -8.5px;
    margin-left: -6px;
}
</style>
